package james.gan.registry.redis;

import java.net.SocketAddress;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;

import com.alibaba.fastjson.JSON;

import james.gan.registry.api.Registry;
import james.gan.registry.api.RegistryCenter;
import james.gan.registry.redis.utils.JedisUtil;
import redis.clients.jedis.Jedis;

public class RedisRegistryCenter extends RegistryCenter {

	private static final Jedis jedis = JedisUtil.getJedis();
	private static final String PREFIX = "registry";

	/**
	 * key: clz-name-status value: json(List<SockAddress>)
	 */
	@Override
	public void registe(SocketAddress socketAddress, Class<?> clz, Registry registryService) {
		String key = getKey(PREFIX, clz.toString(), registryService.getStatus().name(), registryService.getName());
		List<SocketAddress> loadSocketAddress = loadSocketAddress(key);
		loadSocketAddress.add(socketAddress);
		storeSocketAddress(key, loadSocketAddress);
	}

	@Override
	public List<SocketAddress> findByClass(Class<?> clz) {
		return loadSocketAddress(getKey(PREFIX, clz.toString(), "*"));
	}

	@Override
	public Registry getRegistry(SocketAddress socketAddress) {
		// todo
		return null;
	}

	@Override
	public String getName() {
		return "redis";
	}

	@Override
	public Map<Class<?>, List<SocketAddress>> findAll() {
		Set<String> keys = jedis.keys(getKey(PREFIX, "*"));
		return keys.stream().map(s -> s.split("-")).map(arr -> arr[1]).peek(System.out::printf).collect(Collectors
				.toMap(s -> JSON.parseObject(s, Class.class), s -> loadSocketAddress(getKey(PREFIX, (String) s, "*"))));

	}

	private static String getKey(String... strs) {
		return String.join("-", strs);
	}

	public List<SocketAddress> loadSocketAddress(String key) {
		String str = jedis.get(key);
		if (str == null || "".equalsIgnoreCase(str.trim())) {
			return new ArrayList();
		}
		return JSON.parseObject(str, List.class);
	}

	public void storeSocketAddress(String key, List<SocketAddress> list) {
		String jsonString = JSON.toJSONString(new ArrayList(new HashSet(list)));
		jedis.set(key, jsonString);
	}
}
